package org.springframework.context;

import java.util.List;
import java.util.Map;
import java.util.Set;

import junit.framework.Assert;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.h2.tinyspring.TestDao;
import com.h2.tinyspring.TestService;

public class ClassPathXmlApplicationContextTest {
   
   @Test
   public void testBeans() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-beans-ctx.xml");
      
      TestService service = ctx.getBean(TestService.class);
      Assert.assertNotNull(service);
      
      Integer val = service.getTestValue();
      Assert.assertNotNull(val);
      Assert.assertEquals(new Integer(4), val);
      
      Assert.assertNotNull(service.getTestDao());
   }
   
   @Test
   public void testBeanConstructor() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-beans-constructor-ctx.xml");
      
      TestDao dao = ctx.getBean("testDao", TestDao.class);
      Assert.assertNotNull(dao);
      
      Assert.assertNotNull(dao.isTestArg());
      Assert.assertTrue(dao.isTestArg());
      
      TestDao dao2 = ctx.getBean("testDao2", TestDao.class);
      Assert.assertNotNull(dao2);
      
      Assert.assertNotNull(dao2.isTestArg());
      Assert.assertTrue(dao2.isTestArg());
   }
   
   @Test
   public void testBeansProperty() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                  "classpath:test-beans-property-ctx.xml");
      
      TestService service = ctx.getBean(TestService.class);
      
      Assert.assertEquals("", service.getTestDao().getFileName());
      Assert.assertEquals("testFileDirectory",
            service.getTestDao().getFileDir());
      
      TestDao dao2 = ctx.getBean("testDao2", TestDao.class);
      Assert.assertNotNull(dao2);
      Assert.assertEquals("testFileDirectory",
            dao2.getFileDir());
   }
   
   @Test
   public void testInitMethod() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                  "classpath:test-beans-property-ctx.xml");
      
      TestService service = ctx.getBean(TestService.class);
      
      Assert.assertEquals("initialized", service.getTestDao().getTestInit());
   }
   
   @Test
   public void testFactory() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-factory-ctx.xml");

      Integer val = ctx.getBean("testValue", Integer.class);
      Assert.assertNotNull(val);
      Assert.assertEquals(new Integer(3), val);
      
      //test depends-on for factories
      String val2 = ctx.getBean("testValue2", String.class);
      Assert.assertNotNull(val2);
      Assert.assertEquals("initialized", val2);
   }
   
   @Test
   public void testStaticFactory() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-static-factory-ctx.xml");

      
      TestDao dao = ctx.getBean(TestDao.class);
      Assert.assertNotNull(dao);
   }
   
   @Test
   public void testImport() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-import-ctx.xml");

      TestService service = ctx.getBean(TestService.class);
      Assert.assertNotNull(service);
      
      Assert.assertNotNull(service.getTestDao());
   }
   
   @Test
   public void testImportClasspath() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-import-classpath-ctx.xml");
      
      TestService service = ctx.getBean(TestService.class);
      Assert.assertNotNull(service);
      
      Assert.assertNotNull(service.getTestDao());
   }
   
   @Test
   public void testClasspathSubDir() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:sub/test-beans-ctx.xml");
      
      TestService service = ctx.getBean(TestService.class);
      Assert.assertNotNull(service);
      
      Assert.assertNotNull(service.getTestDao());
   }
   
   @Test
   public void testPlaceholder() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-placeholder-ctx.xml");
      
      TestDao dao = ctx.getBean(TestDao.class);
      Assert.assertEquals("TestWarDir", dao.getFileDir());
   }
   
   @SuppressWarnings("unchecked")
   @Test
   public void testUtil() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-util-ctx.xml");
      
      List<String> list = ctx.getBean("list", List.class);
      Assert.assertNotNull(list);
      Assert.assertEquals("test", list.get(0));
      Assert.assertEquals("test2", list.get(1));
      Assert.assertEquals("", list.get(2));
      Assert.assertEquals("testRef", list.get(3));
      Assert.assertEquals("testRef", list.get(4));
      
      Set<String> set = ctx.getBean("set", Set.class);
      Assert.assertNotNull(set);
      Assert.assertTrue(set.contains("test"));
      Assert.assertTrue(set.contains("test2"));
      Assert.assertTrue(set.contains(""));
      Assert.assertTrue(set.contains("testRef"));
   }
   
   @Test
   public void testUtilGeneric() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-util-ctx.xml");
      
      TestDao dao = ctx.getBean(TestDao.class);
      Assert.assertNotNull(dao);
      Assert.assertNotNull(dao.getTestUtil());
      
      Assert.assertEquals("0", dao.getTestUtil().get(0));
      Assert.assertEquals("1", dao.getTestUtil().get(1));
   }
   
   @SuppressWarnings("unchecked")
   @Test
   public void testUtilMap() {
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "classpath:test-util-map-ctx.xml");
      
      Map<String, String> map = ctx.getBean("map", Map.class);
      Assert.assertNotNull(map);
      Assert.assertEquals("testBlaBla", map.get("keyNumberOne"));
      Assert.assertEquals("", map.get("keyNumberTwo"));
      Assert.assertTrue(map.size() == 2);
   }
   
   @Test
   public void testAbstract() {
      
   }
   
   @Test
   public void testScope() {
      
   }

}
